<?php
namespace App\Services;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Cache;
use App\Models\Worklinkback;
use App\Models\Worklinkrecord;
use Log;

class CallbackService
{
    public static function wxkfCallBack($kfid,$record_id,$eventMethod,$back_platfrom)
    {
        $workLinkBack = Cache::get("wxkf_back_".$back_platfrom."_".$kfid);
        if(empty($workLinkBack)) {
            $workLinkBack = Worklinkback::getWorkLinkBackPlatfrom($kfid,$back_platfrom);
            if (empty($workLinkBack)) {
                Cache::put("wxkf_back_".$back_platfrom."_".$kfid,[],6000);
            } else {
                Cache::put("wxkf_back_".$back_platfrom."_".$kfid, $workLinkBack,6000);
            }
        }
        if (empty($workLinkBack)) return ["status"=>"error","code"=>"1","message"=>"当前未配置回传!"];
        $eventActive = $workLinkBack["event_active"];
        if ($eventMethod != "handle" && $eventActive != $eventMethod) {
            return ["status"=>"error","code"=>"5","message"=>"未命中回调"];
        }

        $workLinkRecordModal = new Worklinkrecord(["tbnum"=>$record_id[0]]);
        $workLinkRecord = $workLinkRecordModal->getWorkLinkRecordByRid($record_id);
        if ($workLinkRecord->callback_status == 2) return ["status"=>"error","code"=>"1","message"=>"已回调，无需重复操作!"];
        if ($workLinkBack["submit_type"] == 2 && $eventMethod != "handle") {
            $workLinkRecordModal->updateWorkLinkRecordCallback($record_id,["callback_status"=>6]);
            return ["status"=>"error","message"=>"6","message"=>"需手动回调"];
        }

        if ($workLinkBack["submit_time"] > 0) {
            $recordTime = strtotime($created_at);
            if (($stepStatus["step_".$eventMethod] - $recordTime) < $workLinkBack["submit_time"]) {
                $workLinkRecordModal->updateWorkLinkRecordCallback($record_id,["callback_status"=>8]);
                return ["status"=>"error","code"=>"8","message"=>"过快不回传"];
            }
        }
        if ($workLinkBack["submit_rate"] < 100 && $eventMethod != "handle") {
            $code = rand(1,100);
            if ($code > $workLinkBack["submit_rate"]) {
                 $workLinkRecordModal->updateWorkLinkRecordCallback($record_id,["callback_status"=>4]);
                return ["status"=>"success","code"=>"4","message"=>"概率不回调"];
            }
        }

        $submitBrowser = json_decode($workLinkBack["submit_browser"],true);
        if (!empty($submitBrowser)) {
            if (!in_array($workLinkRecord->browser, $submitBrowser)) {
                $workLinkRecordModal->updateWorkLinkRecordCallback($record_id,["callback_status"=>7]);
                return ["status"=>"error","message"=>"7","message"=>"环境不回传"];
            }
        }
        // 获取转化目标
        $transform_target = $workLinkBack["transform_target"];
        $clickid = $workLinkRecord->clickid;
        if ($back_platfrom == "dy") {
            $backResult = self::douyinCallBack($kfid,$clickid,$transform_target);
        } elseif ($back_platfrom == "bd") {
            $backResult = self::baiduCallBack($kfid,$clickid,$transform_target,$workLinkBack["domain"],$workLinkBack["other"]);
        } elseif ($back_platfrom == "zh") {
            $backResult = self::zhihuCallBack($kfid,$clickid,$transform_target);
        } elseif ($back_platfrom == "xmly") {
            $backResult = self::xmlyCallBack($kfid,$clickid,$transform_target,$workLinkBack["adid"]);
        } elseif ($back_platfrom == "bili") {
            $backResult = self::biliCallBack($kfid,$clickid,$transform_target);
        } elseif ($back_platfrom == "gdt") {
            $backResult = self::gdtCallBack($kfid,$clickid,$transform_target);
        } elseif ($back_platfrom == "oppo") {
            $backResult = self::oppoCallBack($kfid,$clickid,$transform_target,$adid,$workLinkBack->assets_id,$workLinkBack->api_id,$workLinkBack->api_key,$ip);
        } elseif ($back_platfrom == "vivo") {
            $backResult = self::vivoCallBack($kfid,$clickid,$transform_target,$adid,$workLinkBack->assets_id,$workLinkBack->api_id,$workLinkBack->api_key,$workLinkBack->other,$record_id);
        } elseif ($back_platfrom == "ks") {
            $backResult = self::ksCallBack($kfid,$clickid,$transform_target);
        } else {
            return ["status"=>"error","message"=>"未配置此类型数据回调!","code"=>5];
        }
        $workLinkRecordModal->updateWorkLinkRecordCallback($record_id,["callback_status"=>$backResult["code"],"callback_status"=>$eventMethod]);
        return $backResult;
    }

    // 抖音API回调 https://event-manager.oceanengine.com/docs/8650/h5_api_docs/
    public static function douyinCallBack($kfid,$clickid,$transform_target)
    {
        try {          
            $client = new Client;
            $time = time()*1000;
            $body = ["event_type"=>$transform_target,"context"=>["ad"=>["callback"=>$clickid]],"timestamp"=>$time];
            $response = $client->request('POST', 'https://analytics.oceanengine.com/api/v2/conversion',['json' => $body]);
            $backdata = json_decode($response->getBody(),true);
            if ($backdata["code"] == 0) {
                return ["status"=>"success","code"=>"2","message"=>$backdata["message"]];
            } else {
                return ["status"=>"error","code"=>$backdata["code"],"message"=>$backdata["message"]];
            }
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"未知错误"];
        }
    }

    // 百度API回调 https://dev2.baidu.com/content?sceneType=0&pageId=101211&nodeId=658&subhead=
    public static function baiduCallBack($kfid,$clickid,$transform_target,$domain,$other)
    {
        $logidurl = $domain."/site/".$kfid."/bd?bd_vid=".$clickid;
        $conversionTypes = [["logidUrl"=>$logidurl,"newType"=>$transform_target]];
        $reqData = ['token'=>$other,'conversionTypes'=>$conversionTypes];
        $client = new Client;
        $response = $client->request('POST', 'https://ocpc.baidu.com/ocpcapi/api/uploadConvertData',['json' => $reqData]);
        $backdata = json_decode($response->getBody(),true);
        if ($backdata["header"]["status"] == 0) {
            return ["status"=>"success","code"=>"2","message"=>$backdata["header"]["desc"]];
        } else {
            return ["status"=>"error","code"=>$backdata["header"]["status"],"message"=>$backdata["header"]["desc"]];
        }
    }

    public static function zhihuCallBack($kfid,$clickid,$transform_target)
    {
        try {
            // 如果成功不会回调,如果失败会报错
            $client = new Client;
            $response = $client->request("GET", "https://xg.zhihu.com/api/v1/track/callback", [
                "query" => ["sessionId" => $clickid,"event" => "api_".$transform_target,"value" => "","ts" => time()]
            ]);
            return ["status"=>"success","code"=>"2","message"=>"回调成功!"];
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"回调失败！"];
        }
    }

    public static function xmlyCallBack($kfid,$clickid,$transform_target,$adid)
    {
        try {
            $client = new Client;
            $request = $client->request("GET", urldecode($clickid)."&event_type=".$transform_target);
            $response = $request->getBody()->getContents();
            $responseData = json_decode($response);
            if ($responseData->type == "SUCCESS") return ["status"=>"success","code"=>"2","message"=>"回调成功!"];
            return ["status"=>"success","code"=>"3","message"=>"回调成功!"];
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"回调失败！"];
        }
    }

    public static function biliCallBack($kfid,$clickid,$transform_target)
    {
        try {
            $client = new Client;
            $response = $client->request("GET", "https://cm.bilibili.com/conv/api/conversion/ad/cb/v1?conv_time=".time()."&conv_type=".$transform_target."&track_id=".$clickid);
            $result = json_decode($response->getBody(),true);
            if ($result["code"] == 0) {
                return ["status"=>"success","code"=>"2","message"=>"回调成功!"];
            } else {
                return ["status"=>"error","code"=>"3","message"=>"回调失败!"];
            }
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"回调失败！"];
        }
    }

    public static function gdtCallBack($kfid,$clickid,$transform_target)
    {
        try {
            $client = new Client;
            $clickIds = explode("|",$clickid);
            $cid = $clickIds[0];
            $link = isset($clickIds[1]) ? $clickIds[1] : "h5.zhb1.com";
            $response = $client->request("GET", "https://tracking.e.qq.com/conv/web?action_time=".time()."&action_type=".$transform_target."&clickid=".$cid."&link=".$link);
            $result = json_decode($response->getBody(),true);
            if ($result["code"] == 0) {
                return ["status"=>"success","code"=>"2","message"=>"回调成功!"];
            } else {
                return ["status"=>"error","code"=>"3","message"=>"回调失败!"];
            }
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"回调失败！"];
        }
    }

    public static function oppoCallBack($kfid,$clickid,$transform_target,$adid,$owner_id,$api_id,$api_key,$ip)
    {
        try {
            $client = new Client;
            $time_stamp = time();
            $sign = sha1($api_id.$api_key.$time_stamp);
            $token = base64_encode($owner_id.",".$api_id.",".$time_stamp.",".$sign);
            $reqData = ["ip"=>$ip,"transformType"=>$transform_target,"ownerId"=>$owner_id,"transformType"=>$transform_target,"pageId"=>$adid,"tid"=>$clickid,"items"=>[],"lbid"=>"1_0_0"];
            $response = $client->request("POST", "https://sapi.ads.oppomobile.com/v1/clue/sendData", [
                "headers" => [
                    "Content-Type"=>"application/json",
                    "Authorization"=>"Bearer ".$token,
                 ],
                'json' => $reqData
            ]);
            $result = json_decode($response->getBody(),true);
            if ($result["code"] == 0) {
                return ["status"=>"success","code"=>"2","message"=>"回调成功!"];
            } else {
                return ["status"=>"error","code"=>"3","message"=>"回调失败!"];
            }
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"回调失败！"];
        }
    }

    public static function vivoCallBack($kfid,$clickid,$transform_target,$adid,$assets_id,$api_id,$api_key,$other,$record_id)
    {
        try {
            $vivoAccessToken = SemService::vivoGetAccessToken($api_id);
            if ($vivoAccessToken["status"] == "error") return ["status"=>"error","code"=>"3","message"=>"密钥错误!"];

            $accessToken = $vivoAccessToken["access_token"];
            $timestamp = time()*1000;
            // 随机字串标识
            $nonce = $record_id;
            // 即为账户ID
            $advertiserId = $assets_id;
            $requestUrl = "https://marketing-api.vivo.com.cn/openapi/v1/advertiser/behavior/upload?access_token=".$accessToken."&timestamp=".$timestamp."&nonce=".$nonce . "&advertiser_id=".$advertiserId;
            $reqData = ["srcType"=>"Web","srcId"=>$other,"pageUrl"=>"https://h5.zhb1.com/sites/20230227/".$kfid.".html","dataList"=>[["cvType"=>$transform_target,"cvTime"=>$timestamp,"cvParam"=>"","cvCustom"=>"","requestId"=>$clickid,"creativeId"=>$adid,"extParam"=>["unionId"=>""]]]];
            $client = new Client;
            $response = $client->request("POST",$requestUrl, [
                "headers" => [
                    "Content-Type"=>"application/json",
                 ],
                'json' => $reqData
            ]);
            $result = json_decode($response->getBody(),true);
            if ($result["code"] == 0) {
                return ["status"=>"success","code"=>"2","message"=>"回调成功!"];
            } else {
                return ["status"=>"error","code"=>"3","message"=>"回调失败!"];
            }
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"回调失败！"];
        }
    }

    // 快手API回调 https://docs.qingque.cn/d/home/eZQDnexll3-ebbtlX3xEDvBN3?identityId=CjC4ixjMTQ
    public static function ksCallBack($kfid,$clickid,$transform_target)
    {
        try {          
            $client = new Client;
            $time = time()*1000;
            $response = $client->request("GET","http://ad.partner.gifshow.com/track/activate?event_type=".$transform_target."&event_time=".$time."&callback=".$clickid);
            $backdata = json_decode($response->getBody(),true);
            if ($backdata["result"] == 1) {
                return ["status"=>"success","code"=>"2"];
            } else {
                return ["status"=>"error","message"=>""];
            }
        } catch (Exception $e) {
            return ["status"=>"error","code"=>"3","message"=>"未知错误"];
        }
    }
}

